package com.ytkj.digitalConstruction.service.role;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ytkj.digitalConstruction.dao.permission.PermissionMapper;
import com.ytkj.digitalConstruction.dao.permission.RolePermissionMapper;
import com.ytkj.digitalConstruction.dao.role.RoleMapper;
import com.ytkj.digitalConstruction.dao.role.UserGroupRoleMapper;
import com.ytkj.digitalConstruction.dao.role.UserRoleMapper;
import com.ytkj.digitalConstruction.entity.role.Role;
import com.ytkj.digitalConstruction.entity.role.UserGroupRole;
import com.ytkj.digitalConstruction.entity.role.UserRole;
import com.ytkj.digitalConstruction.entity.user.UserGroup;
import com.ytkj.digitalConstruction.httpbean.role.reqbean.SaveRolePermission;
import com.ytkj.digitalConstruction.httpbean.role.resbean.ReturnFlowPermission;
import com.ytkj.digitalConstruction.httpbean.role.resbean.ReturnMenuPermission;
import com.ytkj.digitalConstruction.service.user.UserGroupService;

/**
 * 角色业务处理类
 * 
 * @author Pete
 * @Date 2017年12月7日
 */
@Service
public class RoleService {

	@Autowired
	private UserRoleMapper userRoleMapper;

	@Autowired
	private UserGroupService userGroupService;

	@Autowired
	private UserGroupRoleMapper userGroupRoleMapper;

	@Autowired
	private RoleMapper roleMapper;

	@Autowired
	private PermissionMapper permissionMapper;

	@Autowired
	private RolePermissionMapper rolePermissionMapper;

	/**
	 * 更新用户角色
	 * 
	 * @param userId
	 * @param roleIds
	 * @return
	 */
	public boolean updateUserRoles(Integer userId, List<Integer> roleIds) {
		List<UserRole> roleList = userRoleMapper.selectAllByUserId(userId);
		List<Integer> existsRoleIds = new ArrayList<>();
		roleList.stream().forEach(o -> existsRoleIds.add(o.getRoleId()));
		List<Integer> needDelIds = new ArrayList<>();
		// 之前有的现在没有的
		for (int i : existsRoleIds) {
			if (roleIds.contains(i)) {
				continue;
			}
			needDelIds.add(i);
		}
		// 删除之前有的，现在没有的
		if (!needDelIds.isEmpty()) {
			userRoleMapper.delByUserIdAndRoleIds(userId, needDelIds);
		}

		// 现在有得之前没有的
		UserRole userRole = new UserRole();
		userRole.setUserId(userId);
		for (int i : roleIds) {
			if (existsRoleIds.contains(i)) {
				continue;
			}
			userRole.setId(null);
			userRole.setRoleId(i);
			userRoleMapper.insertSelective(userRole);
		}
		return true;
	}

	/**
	 * 获取用户角色
	 * 
	 * @param userId
	 * @return
	 */
	public List<Role> getUserRoles(Integer userId) {
		List<Role> list = new ArrayList<>();
		Set<Integer> userRoleIds = getUserRoleIds(userId);
		for (Integer userRoleid : userRoleIds) {
			list.add(roleMapper.selectByPrimaryKey(userRoleid));
		}
		return list;
	}

	/**
	 * 获取用户角色
	 * 
	 * @param userId
	 * @return
	 */
	public Set<Integer> getUserRoleIds(Integer userId) {
		Set<Integer> list = new HashSet<Integer>();
		List<UserRole> userRoles = userRoleMapper.selectAllByUserId(userId);
		for (UserRole ur : userRoles) {
			list.add(ur.getRoleId());
		}
		// 获取用户所在的所有用户组
		List<UserGroup> userGroups = userGroupService.getUserGroupByUserId(userId);
		for (UserGroup userGroup : userGroups) {
			List<UserGroupRole> userGroupRoles = userGroupRoleMapper.selectByUserGroupId(userGroup.getUserGroupId());
			for (UserGroupRole userGroupRole : userGroupRoles) {
				list.add(userGroupRole.getRoleId());
			}
		}
		return list;
	}

	/**
	 * 获取用户角色
	 * 
	 * @param userId
	 * @return
	 */
	public Set<Integer> getUserRoleIdsByUserId(Integer userId) {
		Set<Integer> list = new HashSet<Integer>();
		List<UserRole> userRoles = userRoleMapper.selectAllByUserId(userId);
		for (UserRole ur : userRoles) {
			list.add(ur.getRoleId());
		}
		return list;
	}

	/**
	 * 获取用户组角色
	 * 
	 * @param userId
	 * @return
	 */
	public Set<Integer> getUserGroupRoleIdsByUserId(Integer userId) {
		Set<Integer> list = new HashSet<Integer>();
		// 获取用户所在的所有用户组
		List<UserGroup> userGroups = userGroupService.getUserGroupByUserId(userId);
		for (UserGroup userGroup : userGroups) {
			List<UserGroupRole> userGroupRoles = userGroupRoleMapper.selectByUserGroupId(userGroup.getUserGroupId());
			for (UserGroupRole userGroupRole : userGroupRoles) {
				list.add(userGroupRole.getRoleId());
			}
		}
		return list;
	}

	/**
	 * 添加角色
	 * 
	 * @param req
	 * @return
	 */
	public Integer add(Role role) {
		// 添加角色
		return roleMapper.insertSelective(role);
	}

	/**
	 * 根据角色名称查询角色
	 * 
	 * @param roleName
	 * @return
	 */
	public List<Role> selectByRoleName(String roleName) {
		// 根据角色名称查询角色
		return roleMapper.selectByRoleName(roleName);
	}
	
	/**
	 * 判断角色名是否已存在
	 * 
	 * @param roleId
	 * @param roleName
	 * @return
	 */
	public boolean isHasRoleName(Integer roleId,String roleName){
		return roleMapper.selectByRoleNameAndNotEqId(roleId,roleName).size() > 0;
	}
	
	/**
	 * 修改角色
	 * 
	 * @param req
	 * @return
	 */
	public Integer update(Role role) {
		// 添加角色
		return roleMapper.updateByPrimaryKeySelective(role);
	}

	/**
	 * 查询全部角色
	 * 
	 * @return
	 */
	public List<Role> selectAll() {
		return roleMapper.selectAll();
	}

	/**
	 * 删除角色
	 * 
	 * @param id
	 * @return
	 */
	public Integer delete(Integer id) {
		//根据角色Id查询该角色是否对应用户
		List<UserRole> userRoleList = userRoleMapper.selectByRoleId(id);
		if(userRoleList.size() > 0) {
			return 1;
		}
		List<UserGroupRole> userGroupRole = userGroupRoleMapper.selectByRoleId(id);
		if(userGroupRole.size() > 0) {
			return 2;
		}
		//根据角色Id查询该角色是否对应用户组
		if (roleMapper.deleteByPrimaryKey(id) < 1) {
			return -1; // 删除失败
		}
		return 0;
	}

	/**
	 * 判断列表中是否含有当前角色id
	 * 
	 * @param roleList
	 * @param role
	 * @return
	 */
	public boolean isHas(List<Role> roleList, Role thisRole) {
		for (Role role : roleList) {
			if (role.getRoleId() == thisRole.getRoleId() && role.getRoleName().equals(thisRole.getRoleName())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 查询当前角色所拥有的菜单权限
	 * 
	 * @param roleId
	 * @return
	 */
	public List<ReturnMenuPermission> getMenuPermissionList(Integer roleId) {
		// 查询当前角色所有权限
		List<Integer> permissionIdList = selectPermissionIdByRoleId(roleId);
		// 查询所有权限树
		List<ReturnMenuPermission> rrpList = getTreeMenuPermission();
		// 判断菜单权限
		setMenuPermission(rrpList, permissionIdList);
		return rrpList;
	}

	/**
	 * 查询当前角色所有权限
	 * 
	 * @param roleId
	 * @return
	 */
	public List<Integer> selectPermissionIdByRoleId(Integer roleId) {
		return rolePermissionMapper.selectPermissionIdByRoleId(roleId);
	}

	/**
	 * 查询当前角色所拥有的流程权限
	 * 
	 * @param roleId
	 * @return
	 */
	public List<ReturnFlowPermission> getFlowPermissionList(Integer roleId) {
		// 查询当前角色所有权限
		List<Integer> permissionIdList = selectPermissionIdByRoleId(roleId);
		// 查询所有流程权限树
		List<ReturnFlowPermission> rrpList = getTreeFlowPermission();
		// 判断流程权限
		setFlowPermission(rrpList, permissionIdList);
		return rrpList;
	}

	/**
	 * 判断菜单权限树
	 * 
	 * @param rrpList
	 * @param permissionIdList
	 */
	private void setMenuPermission(List<ReturnMenuPermission> rrpList, List<Integer> permissionIdList) {
		// 循环菜单，查看是否包含当前菜单权限
		for (ReturnMenuPermission rrp : rrpList) {
			if (permissionIdList.contains(rrp.getId())) {
				rrp.setHave(true);
			} else {
				rrp.setHave(false);
			}
			// 如果当前菜单没有子菜单则continue
			if (rrp.getChildren() == null) {
				continue;
			}
			// 如果有子菜单则递归判断
			setMenuPermission(rrp.getChildren(), permissionIdList);
		}
	}

	/**
	 * 判断流程权限树
	 * 
	 * @param rrpList
	 * @param permissionIdList
	 */
	private void setFlowPermission(List<ReturnFlowPermission> rrpList, List<Integer> permissionIdList) {
		// 循环菜单，查看是否包含当前菜单权限
		for (ReturnFlowPermission rrp : rrpList) {
			if (permissionIdList.contains(rrp.getId())) {
				rrp.setHave(true);
			} else {
				rrp.setHave(false);
			}
			// 如果当前菜单没有子菜单则continue
			if (rrp.getChildren() == null) {
				continue;
			}
			// 如果有子菜单则递归判断
			setFlowPermission(rrp.getChildren(), permissionIdList);
		}
	}

	/**
	 * 获取所有菜单权限(平级结构)
	 * 
	 * @return
	 */
	public List<ReturnMenuPermission> getAllMenuPermission() {
		// 查询所有菜单权限
		return permissionMapper.selectMenuPermission();
	}

	/**
	 * 获取所有流程权限(平级结构)
	 * 
	 * @return
	 */
	public List<ReturnFlowPermission> getAllFlowPermission() {
		// 查询所有菜单权限
		return permissionMapper.selectFlowPermission();
	}

	/**
	 * 获取所有菜单权限(树级结构)
	 * 
	 * @return
	 */
	public List<ReturnMenuPermission> getTreeMenuPermission() {
		// 查询所有菜单权限
		List<ReturnMenuPermission> rrpList = getAllMenuPermission();
		List<ReturnMenuPermission> returnList = new ArrayList<ReturnMenuPermission>();
		while (true) {
			// 如果待处理列表为空则返回数据
			if (rrpList.size() == 0) {
				return returnList;
			}
			// 循环组织树结构
			for (ReturnMenuPermission rrp : rrpList) {
				if (setMenuTree(returnList, rrp) != null) {
					rrpList.remove(rrp);
					break;
				}
			}
		}
	}

	/**
	 * 获取所有流程权限(树级结构)
	 * 
	 * @return
	 */
	public List<ReturnFlowPermission> getTreeFlowPermission() {
		// 查询所有菜单权限
		List<ReturnFlowPermission> rrpList = getAllFlowPermission();
		List<ReturnFlowPermission> returnList = new ArrayList<ReturnFlowPermission>();
		while (true) {
			// 如果待处理列表为空则返回数据
			if (rrpList.size() == 0) {
				return returnList;
			}
			// 循环组织树结构
			for (ReturnFlowPermission rrp : rrpList) {
				if (setFlowTree(returnList, rrp) != null) {
					rrpList.remove(rrp);
					break;
				}
			}
		}
	}

	/**
	 * 组织菜单树结构
	 * 
	 * @param rrpList
	 * @param thisrrp
	 * @return
	 */
	private List<ReturnMenuPermission> setMenuTree(List<ReturnMenuPermission> rrpList, ReturnMenuPermission thisrrp) {
		// 先把根节点加入返回数据中
		if (thisrrp.getpId() == 0) {
			rrpList.add(thisrrp);
			return rrpList;
		}
		// 循环当前节点数据，陆续加入
		for (ReturnMenuPermission rrp : rrpList) {
			// 如果menuId == 当前pId，则该菜单在当前菜单下
			if (rrp.getMenuId() == thisrrp.getpId()) {
				List<ReturnMenuPermission> childrenList = rrp.getChildren();
				if (childrenList == null) {
					childrenList = new ArrayList<ReturnMenuPermission>();
				}
				childrenList.add(thisrrp);
				rrp.setChildren(childrenList);
				return rrpList;
			}
			// 否则递归循环子节点数据
			if (rrp.getChildren() != null) {
				List<ReturnMenuPermission> childrenList = setMenuTree(rrp.getChildren(), thisrrp);
				if (childrenList != null) {
					rrp.setChildren(childrenList);
					return rrpList;
				}
			}
		}
		// 如果都不满足则返回Null
		return null;
	}

	/**
	 * 组织菜单树结构
	 * 
	 * @param rrpList
	 * @param thisrrp
	 * @return
	 */
	private List<ReturnFlowPermission> setFlowTree(List<ReturnFlowPermission> rrpList, ReturnFlowPermission thisrrp) {
		// 先把根节点加入返回数据中
		if (thisrrp.getpId() == 0) {
			rrpList.add(thisrrp);
			return rrpList;
		}
		// 循环当前节点数据，陆续加入
		for (ReturnFlowPermission rrp : rrpList) {
			// 如果flowId == 当前pId，则该流程节点在当前流程节点下
			if (rrp.getFlowId() == thisrrp.getpId()) {
				List<ReturnFlowPermission> childrenList = rrp.getChildren();
				if (childrenList == null) {
					childrenList = new ArrayList<ReturnFlowPermission>();
				}
				childrenList.add(thisrrp);
				rrp.setChildren(childrenList);
				return rrpList;
			}
			// 否则递归循环子节点数据
			if (rrp.getChildren() != null) {
				List<ReturnFlowPermission> childrenList = setFlowTree(rrp.getChildren(), thisrrp);
				if (childrenList != null) {
					rrp.setChildren(childrenList);
					return rrpList;
				}
			}
		}
		// 如果都不满足则返回Null
		return null;
	}

	/**
	 * 根据角色Id删除所有权限
	 * 
	 * @param roleId
	 */
	public void deletePermission(Integer roleId) {
		rolePermissionMapper.deleteByRoleId(roleId);
	}

	/**
	 * 给角色添加权限
	 * 
	 * @param saveRolePermission
	 */
	public void insert(SaveRolePermission saveRolePermission) {
		if(saveRolePermission.getPermissionList().size() > 0) {
			rolePermissionMapper.savePermission(saveRolePermission);
		}
	}

	/**
	 * 根据用户获取所有角色权限
	 * 
	 * @param userId
	 * @return
	 */
	public List<ReturnMenuPermission> getMenuPermissionListByUserId(Integer userId) {
		Set<Integer> permissionIdSet = getPermissionListByUserId(userId);
		// 查询所有权限树
		List<ReturnMenuPermission> rrpList = getTreeMenuPermission();
		// 判断菜单权限
		List<Integer> permissionIdList = new ArrayList<Integer>();
		permissionIdList.addAll(permissionIdSet);
		setMenuPermission(rrpList, permissionIdList);
		return rrpList;
	}

	/**
	 * 根据用户获取所有流程权限
	 * 
	 * @param userId
	 * @return
	 */
	public List<ReturnFlowPermission> getFlowPermissionListByUserId(Integer userId) {
		Set<Integer> permissionIdSet = getPermissionListByUserId(userId);
		// 查询所有流程权限树
		List<ReturnFlowPermission> rrpList = getTreeFlowPermission();
		// 判断流程权限
		List<Integer> permissionIdList = new ArrayList<Integer>();
		permissionIdList.addAll(permissionIdSet);
		setFlowPermission(rrpList, permissionIdList);
		return rrpList;
	}

	/**
	 * 根据当前登录用户获取权限列表
	 * 
	 * @param userId
	 * @return
	 */
	public Set<Integer> getPermissionListByUserId(Integer userId) {
		List<Role> roleList = getUserRoles(userId);
		Set<Integer> permissionIdSet = new HashSet<Integer>();
		// 查询当前用户所有角色所有权限
		for (Role role : roleList) {
			permissionIdSet.addAll(selectPermissionIdByRoleId(role.getRoleId()));
		}
		return permissionIdSet;
	}

	/**
	 * 根据角色id列表和角色名（精确）查询用户
	 * 
	 * @param roleIds
	 * @param string
	 * @return
	 */
	public List<Role> findByIdsAndName(List<Integer> roleIds, String roleName) {
		List<Role> roleList = roleMapper.selectByRoleIdsAndRoleId(roleIds,roleName);
		return roleList;
	}
}
